﻿// SerialThread.cpp: 实现文件
//

#include "pch.h"
#include "SerialThread.h"


// SerialThread

SerialThread::SerialThread()
{
}

SerialThread::~SerialThread()
{
}

// SerialThread 消息处理程序
void SerialThread::setPortName(int i)
{
	i++;
	if (i <= 9)
	{
		COMX.Format(L"COM%d", i);
	}
	else if (i>0)
	{
		COMX.Format(L"\\\\.\\COM%d", i);
	}
	else
	{
		COMX.Format(L"COM0");
	}
}

void SerialThread::setBaudrate(int bdr)
{
	this->bdr = bdr;
}

void SerialThread::setStopbit(int i)
{
	this->stp = i;
}	

void SerialThread::setParity(int i)
{
	this->prt = i;
}

void SerialThread::setIMUDevice(DeviceID device)
{
	this->device = device;
	switch (device)
	{
	case DeviceID::HFOG:
		numChanel = 1;
		strcpy_s(head[0], IMUpkgHead[0]);
		pkglen = IMUpkglen[0];
		break;
	case DeviceID::OFOG:
		numChanel = 1;
		strcpy_s(head[0], IMUpkgHead[1]);
		pkglen = IMUpkglen[1];
		break;
	case DeviceID::STIM300:
		numChanel = 1;
		strcpy_s(head[0], IMUpkgHead[2]);
		pkglen = IMUpkglen[2];
		break;
	case DeviceID::PSINSBoard:
		numChanel = 1;
		strcpy_s(head[0], IMUpkgHead[3]);
		pkglen = IMUpkglen[3];
		break;
	case DeviceID::Xsens_MTi:
		numChanel = 1;
		strcpy_s(head[0], IMUpkgHead[4]);
		pkglen = IMUpkglen[4];
		break;
	default:
		break;
	}
}

void SerialThread::setGNSSDevice(DeviceID device, GNSSTask task)
{
	this->task = task;
	strcpy_s(initcmd, ReceiverCMD[(int)device-5][(int)task]);
	switch (task)
	{
	case GNSSTask::SP:
		numChanel = 3;
		strcpy_s(head[0], GNSSpkgHead[0]);
		strcpy_s(head[1], GNSSpkgHead[1]);
		strcpy_s(head[2], GNSSpkgHead[5]);		// GNGGA判断
		break;
	case GNSSTask::TI:
		numChanel = 3;
		strcpy_s(head[0], GNSSpkgHead[2]);
		strcpy_s(head[1], GNSSpkgHead[3]);
		strcpy_s(head[2], GNSSpkgHead[4]);
		break;
	case GNSSTask::RTK:
		numChanel = 3;
		strcpy_s(head[0], GNSSpkgHead[0]);
		strcpy_s(head[1], GNSSpkgHead[1]);
		strcpy_s(head[2], GNSSpkgHead[5]);
		break;
	default:
		break;
	}
}

/************************************************/
/*	打开串口										*/
/************************************************/
BOOL SerialThread::openPort()
{
	hdlSerial = CreateFile(COMX, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hdlSerial == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	else 
	{
		GetCommState(hdlSerial, &dcb);
		dcb.BaudRate = bdr;
		dcb.StopBits = stp;
		dcb.Parity = prt;
		dcb.ByteSize = 8;
		SetCommState(hdlSerial, &dcb);
		SetupComm(hdlSerial, 1024, 1024);
		PurgeComm(hdlSerial, PURGE_TXCLEAR | PURGE_RXCLEAR);
		headlen = max(strlen(head[0]), max(strlen(head[1]), strlen(head[2])));
		return TRUE;
	}
	return 0;
}

/************************************************/
/*	关闭串口										*/
/************************************************/
BOOL SerialThread::closePort()
{
	return CloseHandle(hdlSerial);
}

/************************************************/
/*	搜索IMU帧头									*/
/************************************************/
BOOL SerialThread::findHead()
{
	CHAR rB;
	BOOL rres;

	rres = ReadFile(hdlSerial, &rB, 1, &wCount, NULL);
	if (rres && rB==head[0][0])
	{
		for (size_t i = 1; i < headlen; i++)
		{
			rres = ReadFile(hdlSerial, &rB, 1, &wCount, NULL);
			if (rres && rB != head[0][i])
				return false;
		}
		readPkg();
		return true;
	}
	return 0;
}

/************************************************/
/*	读取IMU数据包								*/
/************************************************/
BOOL SerialThread::readPkg()
{
	BOOL res = ReadFile(hdlSerial, buffer, pkglen, &wCount, NULL);
	return res;
}

/************************************************/
/*	搜索GNSS帧头									*/
/************************************************/
BOOL SerialThread::findGNSSHead()
{
	CHAR rB;
	BOOL rres;
	getHead[0] = TRUE;
	getHead[1] = TRUE;
	getHead[2] = TRUE;

	rres = ReadFile(hdlSerial, &rB, 1, &wCount, NULL);
	if (rres && (rB == head[0][0] || rB == head[1][0] || rB == head[2][0]))
	{
		for (size_t i = 1; i < headlen; i++)
		{
			INT res = 0;
			rres = ReadFile(hdlSerial, &rB, 1, &wCount, NULL);
			for (size_t j = 0; j < (UINT)numChanel; j++)
			{
				if (rres && rB != head[j][i])
					getHead[j] = FALSE;
				res += getHead[j];
			}

			// 不存在完全匹配的情况，结束此次搜索
			if (res == 0)
			{
				return FALSE;
			}

			// 发现其中一个完整帧头则退出循环
			if ((getHead[0] == TRUE && i == strlen(head[0]) - 1) ||
				(getHead[1] == TRUE && i == strlen(head[1]) - 1) ||
				(getHead[2] == TRUE && i == strlen(head[2]) - 1) )
			{
				readGNSSPkg();
				return true;
			}
		}
	}
	return 0;
}

/************************************************/
/*	读取GNSS数据包								*/
/************************************************/
BOOL SerialThread::readGNSSPkg()
{
	BOOL pReadState;
	CHAR ch1 = '0', ch2 = '0';
	INT i = 0;		// buf写指针

	UINT buflen = 4096;
	while (buflen--)
	{
		pReadState = ReadFile(hdlSerial, &ch2, 1, &wCount, NULL);
		if (pReadState)
		{
			buffer[i++] = ch2;
			if (ch1 == '\r' && ch2 == '\n')
			{
				buffer[i++] = '\0';		//字符串结束标志
				GNSSpkglen = i;
				break;
			}
			ch1 = ch2;
		}
	}
	return TRUE;
}

/************************************************/
/*	发送接收机初始化指令							*/
/************************************************/
BOOL SerialThread::sendReceiverCMD()
{
	int len = strlen(initcmd);
	BOOL res = WriteFile(hdlSerial, initcmd, len, &wCount, NULL);
	return res;
}
